﻿using DeepEarth.Toolkit.Common;
using System.Windows;
using System.Windows.Controls;
using DeepEarth.Map.Core;
using System;
namespace DeepEarth.Toolkit.Controls
{
    [TemplatePart(Name = PART_scaleTextBlock, Type = typeof(TextBlock))]
    [TemplatePart(Name = PART_newScaleText, Type = typeof(TextBox))]
    [TemplatePart(Name = PART_btnChangeScaleValue, Type = typeof(Button))]
    [TemplateVisualState(Name = VSM_Normal, GroupName = VSM_CommonStates)]
    [TemplateVisualState(Name = VSM_MouseOver, GroupName = VSM_CommonStates)]
    public class ScalePanel : MapInteractionControl
    {
        private const string PART_scaleTextBlock = "PART_scaleTextBlock";
        private const string PART_newScaleText = "PART_newScaleText";
        private const string PART_btnChangeScaleValue = "PART_btnChangeScaleValue";
        private const string VSM_CommonStates = "CommonStates";
        private const string VSM_MouseOver = "MouseOver";
        private const string VSM_Normal = "Normal";

        private bool isMouseOver;
        private TextBlock scaleTextBlock;
        private TextBox newScaleText;
        private Button btnChangeScaleValue;

        public ScalePanel()
        {
            IsEnabled = false;
            DefaultStyleKey = typeof(ScalePanel);
        }

        public override void OnApplyTemplate()
        {
            base.OnApplyTemplate();
            scaleTextBlock = (TextBlock)GetTemplateChild(PART_scaleTextBlock);
            newScaleText = (TextBox)GetTemplateChild(PART_newScaleText);
            btnChangeScaleValue = (Button)GetTemplateChild(PART_btnChangeScaleValue);

            IsEnabled = true;

            btnChangeScaleValue.Click += new RoutedEventHandler(btnChangeScaleValue_Click);

        }

        protected override void MapChanged(IMap newMap, IMap oldMap)
        {
            newMap.ViewChangeOnFrame += Map_ViewChangeOnFrame;
        }

        void Map_ViewChangeOnFrame(object sender, EventArgs e)
        {
            SetMapScale();
        }


        void btnChangeScaleValue_Click(object sender, RoutedEventArgs e)
        {
            double d;
            if (double.TryParse(newScaleText.Text, out d))
            {
                double desiredViewportWidth = GetViewportWidth(Map.View.ViewportWidth, d);

                Map.View.SetLocation(Map.View.Center, desiredViewportWidth);
            }
        }

        private void SetMapScale()
        {
            scaleTextBlock.Text = string.Format("Showing: {0}m", Math.Round(GetViewportMeters(Map.View.Center.Latitude), 0));
        }

        const double EarthRadius = 6378137;

        // http://rashidfaridi.wordpress.com/2008/04/22/mercator-projection/
        public double GetViewportMeters(double latitude)
        {           
            // convert to radians
            double theta = latitude * Math.PI / 180.0;
            double circumferenceAtTheta = 2 * Math.PI * EarthRadius * Math.Cos(theta);
            double viewportWidthInMeters = Map.CurrentViewportLogicalWidth * circumferenceAtTheta;

            return viewportWidthInMeters;
            
        }

        public double GetViewportWidth(double latitude, double meters)
        {
            double theta = latitude * Math.PI / 180.0;
            double circumferenceAtTheta = 2 * Math.PI * EarthRadius * Math.Cos(theta);
            double viewportWidth = meters / circumferenceAtTheta;

            return viewportWidth;
        }
    }
}
